#include "lib.h"
#include "pathname.h"
#include "dir.h"		// for Directory::sep

PathName::PathName()
{
}

PathName::PathName(const String& copy)
{
	set(copy);
}


PathName::~PathName()
{
}

void
PathName::makeEmpty()
{
	path.empty();
}

void
PathName::shrink(int32 numChars)
{
	int32 len = path.getLength();

    if ( len == 0 )
    {
        // nothing to shrink
        return;
    }

	if (numChars >= 0)
	{
		len -= numChars;
		if (len < 0)
			len = 0;
	}
	else
		len = 0;

    path.setChar( len, '\0' );
}

bool8
PathName::set(const String& NewPath)
{
	path = NewPath;
	return true;
}

bool8
PathName::concat(const String& Tail, DirSepOption AddDirSep)
{
	int32 ln = Tail.getLength();

	if (ln <= 0)
		return true;

	if (AddDirSep)
	{
		if (endsWith(Directory::sep))
		{
			if (Tail[0] == Directory::sep)
				shrink(1);
		}
		else
		{
			// only add dirSep between two non-zero-length names
			//
			if (path.getLength() > 0 && Tail[0] != Directory::sep)
			{
				path += Directory::sep;
			}
		}
	}

	path += Tail;

	return true;
}


bool8
PathName::concat(const String::Character& ch)
{
	path += String(ch);
	
	return true;
}

bool8
PathName::operator==(const PathName& Test)
{
	int32 flag = 0;
	bool8 result;

	// equal if either or neither have trailing dirSep
	//
	if (Test.endsWith(Directory::sep))
	{
		if (!endsWith(Directory::sep))
		{
			flag = 1;
			concat(Directory::sep);
		}
	}
	else
	{
		if (endsWith(Directory::sep))
		{
			flag = 2;
			shrink(1);
		}
	}

	result = (bool8)(path.caseCompare((const String&)Test) == 0);
	
	if (flag)
	{
		if (flag == 1)
			shrink(1);
		else if (flag == 2)
			concat(Directory::sep);
	}

	return result;
}

bool8
PathName::endsWith(const String::Character& Ch) const
{
	ASSERT(path.getLength() >= 0);

	return (bool8)(path.getLength() > 0 && path[path.getLength() - 1] == Ch);
}

void
PathName::replace(const String::Character& Find, const String::Character& With)
{
	if (Find == '\0' || With == '\0' || Find == With)
		return;

	path.replace(Find, With);
}

uint32
PathName::getEndPos() const
{
	int32 i;

	for (i = path.getLength() - 1; i >= 0; i--)
		if (path[i] == Directory::sep)
			return i;

	return 0;
}

String
PathName::getEnd() const
{
	int32 i;

	for (i = path.getLength() - 1; i >= 0; i--)
		if (path[i] == Directory::sep)
			return path.substring(i + 1);

	return "";
}

void
PathName::removeEnd()
{
	shrink(path.getLength() - getEndPos());
}
